import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.rsbot.script.*;
import org.rsbot.script.methods.Game;
import org.rsbot.script.methods.Skills;
import org.rsbot.script.wrappers.*;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.ServerMessageListener;
import org.rsbot.event.events.ServerMessageEvent;

@ScriptManifest(authors = { "Ragon" }, keywords = "Crafting", description = "Settings in the GUI! Start at seer's village or at seer's flax.", 
		name = "Ragon's Flax Combo", version = 3.02)
public class RagonFlaxCombo extends Script implements ServerMessageListener,PaintListener,ActionListener,ItemListener,MouseMotionListener{

	final ScriptManifest properties = getClass().getAnnotation(ScriptManifest.class);
	int picked;
	int bankid = 25808;
	int flaxid = 1779;
	int stringid = 1777;
	int pickflaxid = 2646;
	int ladderid = 25938;
	int uladderid = 25939;
	int spinnerid = 25824;
	int doorclosedid = 25819;
	int spinid = 1563;
	int pickingid = 827;
	int npc = 388;
	int logoutafter = -1;
	int stexp;
	int fmoneymade,smoneymade,craftinglvl,exp,nextlvl,movedcam;
	int speed = 8;
	long chr, fmoneyhr, smoneyhr, fhr;
	long totalseconds;
	boolean spinflax = false;
	boolean startloop = false;
	boolean loaselected = false;
	double version = properties.version();
	Color back = new Color(255,0,0,125);
	RSTile inside = new RSTile(2714,3471);
	RSTile[] banktoflax = { new RSTile(2725,3492), new RSTile(2727,3479),
			new RSTile(2728,3465), new RSTile(2729,3455),
			new RSTile(2733,3444), new RSTile(2741,3443)
	};
	RSTile[] flaxtobank;
	RSTile[] flaxtospinner = { new RSTile(2733,3444), new RSTile(2727,3453),
			new RSTile(2722,3463), new RSTile(2717,3471)
	};
	RSTile[] spinnertobank = { new RSTile(2718,3482), new RSTile(2725,3491)
	};
	RSTile[] banktospinner;
	RSTile Uspin = new RSTile(2714,3472);
	GEItemInfo flaxp;
	GEItemInfo stringp;
	long starttime;
	long milli;
	long hour;
	long min;
	long sec;
	DecimalFormat format = new DecimalFormat("00");
	String ssec = format.format(sec);
	String smin = format.format(min);
	String shour = format.format(hour);
	String timer = shour + ":" + smin + ":" + ssec;
	
	JFrame frame = new JFrame("Ragon's Flax Combo " + version);
	JButton start = new JButton("Start!");
	JButton cancel = new JButton("Cancel");
	JCheckBox spinbox = new JCheckBox("Spin the flax?");
	JCheckBox elogouta = new JCheckBox("Do you want to Logoutafter?");
	JTextField logouta = new JTextField(16);
	JLabel speedinfo = new JLabel("Set mouse speed. Higher = slower & Lower = faster. Default = 8");
	JTextField speedset = new JTextField(10);
	
	Font font = new Font("Arial",Font.PLAIN,30);
	Font font2 = new Font("Arial",Font.PLAIN,13);
	
	Rectangle prect = new Rectangle(365,300,151,35); //Picked rectangle
	Rectangle irect = new Rectangle(200,300,170,35); //Info Rectangle
	Rectangle exprect = new Rectangle(55,300,150,35); //Experience Rectangle
	Font mainf = new Font("Arial",Font.PLAIN,14);
	
	Point rm = new Point();
	
	public RagonFlaxCombo(){
		start.addActionListener(this);
		cancel.addActionListener(this);
		spinbox.addItemListener(this);
		elogouta.addItemListener(this);
	}
	public String getScriptDescription(){
		String des = properties.description();
		return des;
	}
    public boolean onStart(){
    	log("<---Started Ragon's Flax Combo!--->");
    	loadVariables();
    	new GUI().MakeGUI();
    	camera.setPitch(true);
        return true;
    }
    public void loadVariables(){
    	stexp = skills.getCurrentExp(Skills.CRAFTING);
    	stringp = grandExchange.loadItemInfo(stringid);
    	flaxp = grandExchange.loadItemInfo(flaxid);
    	banktospinner = walking.reversePath(spinnertobank);
    	flaxtobank = walking.reversePath(banktoflax);
    }
	public class GUI extends JPanel{
		
		public void MakeGUI(){
			frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
			frame.setSize(450,310);
			frame.setResizable(false);
			frame.add(new GUI());
			frame.setVisible(true);
		}
		public GUI(){
			setLayout(null);
			start.setBounds(235,245,100,30);
			cancel.setBounds(340,245,100,30);
			spinbox.setBounds(250,50,190,40);
			elogouta.setBounds(20,50,190,40);
	        speedinfo.setBounds(20, 170, 350, 20);
	        speedset.setBounds(40, 200, 150, 20);
	        speedset.setText("8");
			add(start);
			add(spinbox);
			add(elogouta);
			add(cancel);
	        add(speedinfo);
	        add(speedset);
		}
		public void paintComponent(Graphics g){
			g.setColor(Color.red);
			g.setFont(font);
			g.drawString("Ragon's Flax Combo!", 70, 35);
			g.drawLine(0, 45, 450, 45);
			if(loaselected == true){
				g.setFont(font2);
				g.setColor(Color.black);
				g.drawString("Ammount of Flax to pick", 50, 140);
				g.drawString("before logging out.", 70, 160);
			}
		}
	}
    public boolean atBank(){
    	RSObject bank = objects.getNearest(bankid);
    	if(bank == null){
    		return false;
    	}
    	return calc.tileOnScreen(bank.getLocation());
    }
    public boolean atFlax(){
    	final RSObject flax = objects.getNearest(pickflaxid);
    	if(flax == null){
    		return false;
    	}else{
    		return calc.tileOnScreen(flax.getLocation());
    	}
    }
    public boolean atSpinner(){
    	RSObject spin = objects.getNearest(ladderid);
    	if(spin == null){
    		return false;
    	}else{
    		return calc.tileOnScreen(spin.getLocation());
    	}
    }
    public boolean atUSpinner(){
    	RSObject spin = objects.getNearest(spinnerid);
    	RSTile tile = walking.getClosestTileOnMap(Uspin);
    	if(spin == null){
    		return false;
    	}else{
    		if(calc.tileOnScreen(spin.getLocation())){
    			return true;
    		}else{
    			if(calc.tileOnScreen(tile)){
    				return true;
    			}else{
    				return false;
    			}
    		}
    	}
    }
    public boolean HandleBank(){
		RSObject bankBooth = objects.getNearest(bankid);
		if(bankBooth == null){
			return false;
		}
		if(bank.isOpen()){
			bank.depositAll();
		}else{
			bankBooth.doAction("Use-quickly");
		}
		return true;
    }
    public boolean walktobank(){
		RSTile[] randomizePath = walking.randomizePath(flaxtobank,3,3);
		return walking.walkPathMM(randomizePath, 15);
    }
    public boolean walktoflax(){
		RSTile[] randomizePath = walking.randomizePath(banktoflax,3,3);
		return walking.walkPathMM(randomizePath, 15);
    }
    public boolean walktospinner(){
		RSTile[] randomizePath = walking.randomizePath(flaxtospinner,3,3);
		return walking.walkPathMM(randomizePath, 15);
    }
    public boolean walktobankfs(){
		RSTile[] randomizePath = walking.randomizePath(spinnertobank,3,3);
		return walking.walkPathMM(randomizePath, 15);
    }
    public boolean pickFlax(){
		final RSObject flax = objects.getNearest(pickflaxid);
		if(getMyPlayer().isMoving()){
			return false;
		}
		if(flax == null){
			return false;
		}else{
			flax.doAction("Pick");
			return true;
		}
    }
    public boolean goupladder(){
		RSObject ladder = objects.getNearest(ladderid);
		if(ladder == null){
			return false;
		}else{
			return ladder.doAction("Climb-up");
		}
    }
    public boolean godownladder(){
		RSObject ladder = objects.getNearest(uladderid);
		if(ladder == null){
			return false;
		}else{
			ladder.doAction("Climb-down");
			return true;
		}
    }
    public boolean Spin(){
		RSObject spinner = objects.getNearest(spinnerid);
    	RSComponent inter = interfaces.getComponent(905, 16);
		if(spinner == null){
			return false;
		}else{
			if(getMyPlayer().getAnimation() == spinid){
				return false;
			}else{
				spinner.doAction("Spin");
				sleep(200);
				inter.doAction("Make All");
				return true;
			}
		}
    }
    public boolean doorclosed(){
		RSObject doorc = objects.getNearest(doorclosedid);
		if(doorc == null){
			return false;
		}else{
			if(calc.tileOnScreen(doorc.getLocation())){
				camera.setAngle(90);
				sleep(300);
				doorc.doAction("Open");
				return true;
			}else{
				return false;
			}
		}
    }
    public boolean edoorclosed(){
		RSObject doorc = objects.getNearest(doorclosedid);
		RSObject obj = objects.getNearest(ladderid);
		if(doorc == null || obj == null){
			return false;
		}
		if(calc.tileOnScreen(doorc.getLocation()) && calc.tileOnScreen(obj.getLocation())){
			return doorc.doAction("Open");
		}else{
			return false;
		}
    }
	public int antiBan(){
		int doantiban = random(1,40);
		switch(doantiban){
		case 1:
			return random(500,800);
		case 2:
			game.openTab(Game.TAB_STATS);
			sleep(random(800,900));
			game.openTab(Game.TAB_INVENTORY);
			return random(500,800);
		case 3:
			mouse.moveSlightly();
		case 4:
			int px = random(20,50);
			int nx = random(-20,-50);
			if(movedcam == 0){
				camera.setAngle(px);
				movedcam++;
			}else{
				camera.setAngle(nx);
				movedcam--;
			}
			return random(500,800);
		case 5:
			game.openTab(Game.TAB_FRIENDS);
			sleep(random(800,900));
			game.openTab(Game.TAB_INVENTORY);
			return random(500,800);
		}
		return random(500,800);
	}
	public int flaxantiBan(){
		int doantiban = random(1,100);
		switch(doantiban){
		case 1:
			return random(200,300);
		case 2:
			int px = random(20,50);
			int nx = random(-20,-50);
			if(movedcam == 0){
				camera.setAngle(px);
				movedcam++;
			}else{
				camera.setAngle(nx);
				movedcam--;
			}
			return random(200,300);
		}
		return random(200,300);
	}
    public int loop() {
    	if(startloop){
    		mouse.setSpeed(random(speed, speed + 2));
    		if(walking.getEnergy() >= random(75,100)){
    			walking.setRun(isActive());
    		}
    		if(logoutafter == picked){
    			stopScript();
    			game.logout(true);
    		}
    		if(spinflax){
    			if(inventory.isFull() && !inventory.containsOneOf(flaxid)){
    				if(atUSpinner() || getMyPlayer().getLevel() == 1){
    					if(godownladder()){
    						camera.setAngle(-90);
    						return random(600,800);
    					}
    				}else{
    					if(atBank()){
    						camera.setAngle(0);
    						if(HandleBank()){
    							return random(1200,1400);
    						}
    					}else{
    						if(edoorclosed()){
    							return random(1000,1200);
    						}
    		    			if(calc.distanceTo(banktoflax[0]) > 5 && !isMoving()){
    		    				if(walktobankfs()){
    		    					return random(200,400);
    		    				}
    		    			}else{
    		    				return random(200,400);
    		    			}
    					}
    				}
    			}else if(inventory.isFull()){
    				if(atSpinner()){
    					if(doorclosed()){
    						return random(1500,2000);
    					}
    					if(goupladder()){
        					return random(1500,2000);
    					}else{
    						return random(1500,2000);
    					}
    				}else if(atUSpinner()){
    					for(int i = 0; i <= 5;i++){
        					if(getMyPlayer().getAnimation() == spinid){
        						return antiBan();
        					}else{
        						sleep(400);
        					}
    					}
    					if(inventory.contains(flaxid)){
    						camera.setAngle(40);
    						if(Spin()){
    							return random(1000,1200);
    						}
    					}
    				}else if(!inventory.contains(stringid)){
    	    			if(calc.distanceTo(spinnertobank[0]) > 5 && !isMoving()){
        					if(walktospinner()){
        						camera.setPitch(true);
        						return random(200,400);
        					}else{
        						walking.walkTo(inside);
        					}
    	    			}else{
    	    				return random(200,400);
    	    			}
    				}else{
    					return random(600,800);
    				}
    			}else{
    				if(atFlax()){
    					if(pickFlax()){
    						return random(200,300);
    					}
    				}else{
    	    			if(calc.distanceTo(flaxtobank[0]) > 2 && !isMoving()){
    	    				if(walktoflax()){
    	    					return random(200,400);
    	    				}
    	    			}else{
    	    				return random(200,400);
    	    			}
    				}
    			}
    		}else{
    			if(inventory.isFull()){
    				if(atBank()){
    					if(HandleBank()){
    						return random(1200,1400);
    					}
    				}else{
    	    			if(calc.distanceTo(banktoflax[0]) > 5 && !isMoving()){
    	    				if(walktobank()){
    	    					return random(200,400);
    	    				}
    	    			}else{
    	    				return random(200,400);
    	    			}
    				}
    			}else{
    				if(atFlax()){
    					if(pickFlax()){
    						return flaxantiBan();
    					}
    				}else{
    	    			if(calc.distanceTo(flaxtobank[0]) > 2 && !isMoving()){
    	    				if(walktoflax()){
    	    					return random(200,400);
    	    				}
    	    			}else{
    	    				return random(200,400);
    	    			}
    				}
    			}
    		}
    		return random(600,800);
    	}else{
    		return random(300,500);
    	}
    }
	public boolean isMoving(){
		if(!getMyPlayer().isMoving()){
			return false;
		}
		if(walking.getDestination() != null){
			if(calc.distanceTo(walking.getDestination()) < 5){
				return false;
			}else{
				return true;
			}
		}
		return false;
	}
    public void onFinish() {
    	log("<---Stopped Ragon's Flax Combo--->");
    	log("<---Ran For " + timer + "--->");
    	log("<---Picked " + picked + " flax!--->");
    	log("<---MoneyMade(F) " + fmoneymade + "--->");
    	log("<---MoneyMade(S) " + smoneymade + "--->");
    }

    public void onRepaint(Graphics g){
		Graphics2D g2 = (Graphics2D) g;
		RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setRenderingHints(rh);
    	craftinglvl = skills.getCurrentLevel(Skills.CRAFTING);
    	nextlvl = skills.getExpToNextLevel(Skills.CRAFTING);
    	exp = skills.getCurrentExp(Skills.CRAFTING) - stexp;
    	if(startloop == true){
       		totalseconds = (System.currentTimeMillis() - starttime) / 1000;
    		milli = System.currentTimeMillis() - starttime;
    		hour = milli  / (1000 * 60 * 60);
    		milli -= hour * 1000 * 60 * 60;
    		min = milli / (1000 * 60);
    		milli -= min * 1000 * 60;
    		sec = milli  / 1000;
    		timer = shour + ":" + smin + ":" + ssec;
    		ssec = format.format(sec);
    		smin = format.format(min);
    		shour = format.format(hour);
    		if(totalseconds == 0){
    		}else{
            	chr = exp * 3600 / totalseconds;
            	fmoneyhr = fmoneymade * 3600 / totalseconds;
            	smoneyhr = smoneymade * 3600 / totalseconds;
            	fhr = picked * 3600 / totalseconds;
    		}
    	}
    	g.setColor(back);
    	g.fillRect(365,300,151,35);
    	g.fillRect(200,300,170,35);
    	g.fillRect(55,300,150,35);
    	g.setColor(Color.black);
    	g.drawRect(365,300,151,35);
    	g.drawRect(200,300,170,35);
    	g.drawRect(55,300,150,35);
    	g.setFont(mainf);
    	g.drawString("Picked", 425, 322);
    	g.drawString("Info", 275, 322);
    	g.drawString("Experience", 95, 322);
    	if(prect.contains(rm)){
    		g.setColor(back);
    		g.fillRect(365, 230, 151, 70);
    		g.setColor(Color.black);
    		g.drawRect(365, 230, 151, 70);
    		g.drawString("Flax Picked: " + picked, 370, 250);
    		g.drawString("Flax/hr: " + fhr, 370, 270);
    		if(logoutafter == -1){
    			g.drawString("Logoutafter: Disabled", 370, 290);
    		}else{
    			g.drawString("Logoutafter: " + logoutafter, 370, 290);
    		}
    	}else if(irect.contains(rm)){
    		g.setColor(back);
    		g.fillRect(200, 170, 170, 130);
    		g.setColor(Color.black);
    		g.drawRect(200, 170, 170, 130);
    		g.drawString("Ragon's Flax Combo " + version, 205, 190);
    		g.drawString("Runtime: " + timer, 205, 210);
    		g.drawString("Money Made(F): " + fmoneymade, 205, 230);
    		g.drawString("Money Made(S): " + smoneymade, 205, 250);
    		g.drawString("Money/hr(F): " + fmoneyhr, 205, 270);
    		g.drawString("Money/hr(S): " + smoneyhr, 205, 290);
    	}else if(exprect.contains(rm)){
    		g.setColor(back);
    		g.fillRect(55, 210, 150, 90);
    		g.setColor(Color.black);
    		g.drawRect(55, 210, 150, 90);
    		g.drawString("Exp Gained: " + exp, 60, 230);
    		g.drawString("Exp/hr :" + chr, 60, 250);
    		g.drawString("Crafting Level: " + craftinglvl, 60, 270);
    		g.drawString("Next level in: " + nextlvl, 60, 290);
    	}
    }

    public void serverMessageRecieved(ServerMessageEvent e) {
        String message = e.getMessage();
        if(message.contains("You pick some flax")){
        	picked++;
        	fmoneymade += flaxp.getMarketPrice();
        	smoneymade += stringp.getMarketPrice();
        }
    }
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == start){
			if(logouta.getText().isEmpty()){
			}else{
				logoutafter = (Integer.valueOf(logouta.getText())).intValue();
			}
			if(speedset.getText().isEmpty()){
				speed = 8;
			}else{
				speed = (Integer.valueOf(speedset.getText())).intValue();
			}
			starttime = System.currentTimeMillis();
			startloop = true;
			frame.dispose();
		}else if(e.getSource() == cancel){
			frame.dispose();
			stopScript();
		}
	}
	public void itemStateChanged(ItemEvent e) {
		if(e.getItemSelectable() == spinbox){
			if(e.getStateChange() == ItemEvent.SELECTED){
				spinflax = true;
			}else{
				spinflax = false;
			}
		}else if(e.getItemSelectable() == elogouta){
			if(e.getStateChange() == ItemEvent.SELECTED){
				logouta.setBounds(10,90,210,30);
				frame.add(logouta);
				loaselected = true;
				frame.repaint();
			}else{
				frame.remove(logouta);
				loaselected = false;
				frame.repaint();
			}
		}
	}
	public void mouseDragged(MouseEvent e) {}
	public void mouseMoved(MouseEvent e) {
		rm = e.getPoint();
	}
}